package ece452.ims.view;

import javax.swing.*;

import java.awt.*;
import java.awt.event.*;

import ece452.ims.connection.Relay;

public class Login extends JPanel implements ActionListener{

	private static JTextField username;
	private static JPasswordField password;
	private JButton login;
	private JButton createAccount;
	public static Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
	private static Relay rl;
	public static JFrame mainFrame;
	private static String servReply;
	private static DefaultListModel listOfFriends;
	public static BuddyList bl;
	private static JFrame bflist;
	
	public Login() {
		
		super(new GridLayout(7, 1));
		
		// Action Listeners
		LoginEvent loginListener = new LoginEvent();
		
		// Create labels for main window
		JComponent welcome = makeTextPanel("Welcome to IMS!");
		JComponent usernameLabel = makeTextPanel("Username");
		JComponent passwordLabel = makeTextPanel("Password");

		username= new JTextField(15); // instantiate new JTextField
		password= new JPasswordField(15);
		
		login = new JButton("Login");
		login.setEnabled(true);
		login.setActionCommand("Login");
		login.addActionListener(loginListener);
		
		createAccount = new JButton("Create A New Account");
		createAccount.setEnabled(true);
		createAccount.setActionCommand("Create Account");
		createAccount.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
				JFrame frame = new JFrame("Create new account");
				frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
				frame.setPreferredSize(new Dimension(200, 350));
				frame.setLocation(screenSize.height/2, screenSize.width/6);
				frame.getContentPane().add(new CreateAccountWindow(rl), BorderLayout.CENTER);
				frame.pack();
				frame.setVisible(true);
				frame.setResizable(false);
			}
		});
		
		login.setToolTipText("Click here to login and view your friends list.");
		createAccount.setToolTipText("Click here to create a new account.");
		
		// padding: top, left, bottom, right
		// Layout for the initial message
		JPanel greeting = new JPanel();
		greeting.setLayout(new FlowLayout(FlowLayout.CENTER));
		greeting.add(welcome);
		greeting.setBorder(BorderFactory.createEmptyBorder(35, 10, 10, 10));

		// Layout and padding for the Login Button
		JPanel buttonLogin = new JPanel();
		buttonLogin.setLayout(new FlowLayout(FlowLayout.CENTER));
		buttonLogin.add(login);
		buttonLogin.setBorder(BorderFactory.createEmptyBorder(15,0,0,0));
		
		// Layout and padding for the Create Account Button
		JPanel buttonCreateAccount = new JPanel();
		buttonCreateAccount.setLayout(new FlowLayout(FlowLayout.CENTER));
		buttonCreateAccount.add(createAccount);
		buttonCreateAccount.setBorder(BorderFactory.createEmptyBorder(0,0,15,0));
		
		// Label for Username
		JPanel labelUsername = new JPanel();
		labelUsername.setLayout(new FlowLayout(FlowLayout.LEFT));
		labelUsername.add(usernameLabel);
		labelUsername.setBorder(BorderFactory.createEmptyBorder(43,10,0,10));
		//labelUsername.setBorder(BorderFactory.createLineBorder(Color.black));

		// Layout and padding for the Username Textbox
		JPanel textBoxUsername = new JPanel();
		//textBoxUsername.setLayout(new FlowLayout(FlowLayout.CENTER)); // text box (tight)
		textBoxUsername.setLayout(new BoxLayout(textBoxUsername, BoxLayout.LINE_AXIS));
		textBoxUsername.add(username);
		textBoxUsername.setBorder(BorderFactory.createEmptyBorder(17,10,17,10));
		
		// Label for the Password
		JPanel labelPwd = new JPanel();
		labelPwd.setLayout(new FlowLayout(FlowLayout.LEFT));
		labelPwd.add(passwordLabel);
		labelPwd.setBorder(BorderFactory.createEmptyBorder(43,10,0,10));
		
		// Layout and padding for the Password Textbox
		JPanel textBoxPassword = new JPanel();
		textBoxPassword.setLayout(new BoxLayout(textBoxPassword, BoxLayout.LINE_AXIS));
		textBoxPassword.add(password);
		textBoxPassword.setBorder(BorderFactory.createEmptyBorder(17,10,17,10));
		
		// Add to frame
		add(greeting);
		add(labelUsername);
		add(textBoxUsername);
		add(labelPwd);
		add(textBoxPassword);
		add(buttonLogin);
		add(buttonCreateAccount);
	}
	
	protected JComponent makeTextPanel(String text) {
		JPanel panel = new JPanel(true);
		JLabel filler = new JLabel(text);
		filler.setHorizontalAlignment(JLabel.CENTER);
		panel.setLayout(new GridLayout(1, 1));
		panel.add(filler);
		return panel;
	}

	public void actionPerformed(ActionEvent e){
		
	}
	
	class LoginEvent implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			// if (!e.paramString().equals("")) login.setEnabled(true);
			//rl.getListOfFriends();
			//makeList("");
			Object source = e.getSource();
			String pwdS = "";
			if (source == login) {
				char[] pwd = password.getPassword();
				for(int i=0; i<pwd.length; ++i){
					pwdS+=pwd[i];
				}
				if (username.getText().equals("")) {
					// new frame that says "invalid username"
					System.out.println("Invalid username.");
					return;
				}
				if(pwdS.equals("")){
					// new frame that says "invalid password"
					System.out.println("Invalid password.");
					return;
				}
				rl.login(username.getText(), pwdS);
				//rl.getListOfFriends();
			}
			//mainFrame.setVisible(false);
		}
	}
	
	public static String getUsername(){
		return username.getText().toString();
	}
	
	public class GetResponse extends Thread{
		public void run(){ rx(); }
		public synchronized void rx(){
			while(true){
				try{
					String servReply = Relay.sin().readLine();
					System.out.println("reply: " + servReply);
					// case based on reply
					int val = Integer.parseInt(servReply.substring(0, servReply.indexOf("`")));
					System.out.println("val is: "+val);
					switch(val){
						case 3:
							String u = servReply.substring(servReply.indexOf("`")+1,servReply.lastIndexOf("`"));
							String m = servReply.substring(servReply.lastIndexOf("`")+1);
							bl.updateChat(u, m);
							if(servReply.equals("4`7`User is not online.")){
								bl.updateChat(u, servReply.substring(servReply.lastIndexOf("`")+1));
							}
							break;
						case 4: 
							if(servReply.equals("4`0")){
								mainFrame.setVisible(false);
								rl.getListOfFriends();
							}
							if(servReply.equals("4`1")){
								displayMessage(1);
							}	
							if(servReply.equals("4`11")) System.exit(0);
							break;
						case 5:
							makeList(servReply);
							if(bl == null){
								bl = new BuddyList(rl, listOfFriends);
							}else{
								bflist.setVisible(false);
								bl = new BuddyList(rl, listOfFriends);
							}
							makeBuddyList(bl);
							break;
						case 6:
							String fa = servReply.substring(servReply.indexOf("`")+1);
							bl.addFriend(fa);
						case 7:
							String fr = servReply.substring(servReply.indexOf("`")+1);
							bl.removeFriend(fr);
						case 9:
							bl.updateList(servReply);
							break;
						case 15:
							bl.updateStatus(servReply,15);
							break;
						case 16:
							bl.updateStatus(servReply,16);
							break;
					}
					
				}catch(Exception e){ }
			}	
		}
		//reply: 4`7`User is not online.
		public void makeList(String seq){
			System.out.println("BL: "+seq);
			listOfFriends = new DefaultListModel();
			if(seq.length() == 0){
				System.out.println("empty list");
				listOfFriends.addElement(""); 
				return; 
			}
			seq = seq.substring(seq.indexOf("`")+1);
			while(seq.indexOf("`") != -1){
				String name = seq.substring(0,seq.indexOf("`"));
				seq = seq.substring(seq.indexOf("`")+1);
				String status = seq.substring(0,seq.indexOf("`"));
				//String status = name.substring(name.indexOf("`"+1));
				seq = seq.substring(seq.indexOf("`")+1);
				System.out.println("name: " + name + " status: " + status);
				listOfFriends.addElement(name+" - "+status);
			}
		}
	}
	
	public void makeBuddyList(BuddyList bl){
		bflist = new JFrame("Friends List");
		bflist.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		// frame.setPreferredSize(new Dimension(320,280));
		bflist.setPreferredSize(new Dimension(250, 520));
		bflist.getContentPane().add(bl, BorderLayout.CENTER);
		bflist.pack();
		bflist.setVisible(true);
		bflist.setJMenuBar(bl.getBLMenuBar());
		bflist.setLocation(screenSize.height/2, screenSize.width/6);
	}
	
	private void displayMessage(int n){
		// series of messageboxes 
		Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
		JComponent message;
		JButton ok = new JButton("OK");
		switch(n){
		case 1:	// account already exists
			message = makeTextPanel("Password is incorrect.");
			break;
		case 2:
			message = makeTextPanel("You must enter a valid password.");
			break;
		case 3:
			message = makeTextPanel("The two passwords do not match.");
			break;
		case 4:
			message = makeTextPanel("You may now login!");
			break;
		default:
			message = makeTextPanel("Default error message.");
			break;
		}
		JPanel okButton = new JPanel();
		okButton.add(ok);
		okButton.setLayout(new FlowLayout(FlowLayout.CENTER));
		okButton.setBorder(BorderFactory.createEmptyBorder(20,20,20,20));
		final JFrame errorFrame = new JFrame("Error: Does Not Compute");
		errorFrame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
		errorFrame.setPreferredSize(new Dimension(450, 200));
		errorFrame.setLocation(screenSize.height/2, screenSize.width/3);
		errorFrame.getContentPane().add(message, BorderLayout.CENTER);
		errorFrame.getContentPane().add(okButton, BorderLayout.PAGE_END);
		errorFrame.pack();
		errorFrame.setVisible(true);
		ok.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				errorFrame.setVisible(false);
			}
		});
	}
	
	public static void showGUI() {
		//screenSize = Toolkit.getDefaultToolkit().getScreenSize();
		Login login = new Login();
		rl = new Relay("172.31.60.148");
		//rl = new Relay("172.31.50.124");
		login.new GetResponse().start();
		mainFrame = new JFrame("Instant Messaging Service Login");
		mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		mainFrame.setPreferredSize(new Dimension(255, 465));
		mainFrame.setLocation(screenSize.height/2, screenSize.width/6);
		mainFrame.getContentPane().add(login, BorderLayout.CENTER);
		mainFrame.pack();
		mainFrame.setVisible(true);
		mainFrame.setResizable(false);
		login.new GetResponse().start();
	}

	public static void main(String[] args) {
		javax.swing.SwingUtilities.invokeLater(new Runnable() {
			public void run() { showGUI(); }
		});
	}	
}
